#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QSqlRecord>

QVector<QMap<QString, QVariant> > Get(QString qs,QSqlQuery query)
{
    QMap<QString, QVariant> ret;
    QVector<QMap<QString, QVariant> > rets;
    query.exec(qs);
    if(query.lastError().text().isEmpty()) {
        QSqlRecord record = query.record();
        while (query.next()){
            uint count = record.count();
            for(uint i=0;i<count;i++){
                QString key = record.fieldName(i);
                // qDebug() << i << key << record.value(key);
                ret.insert(key,query.value(i));
            }
            rets.push_back(ret);
        }
    }
    return rets;
}


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    auto desktop = SystemVal::GetInstance()->desktop;
    move((desktop->width()-this->width())/2,(desktop->height()-this->height())/2);


}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initUI()
{
    loadFromOri();
    buf = new QStringListModel;
    ui->list_W1->setModel(buf);
}

void MainWindow::loadFromOri()
{
    auto &ori = SystemVal::GetInstance()->old_Data;
    for (auto it = ori.begin();it!=ori.end();it++) {
        QListWidgetItem  *asere = new QListWidgetItem(QString::number(it.key()));
        auto sss = it->value("SEAMINFO");   //! 获取焊缝信息表的数据们
        asere->setToolTip(sss.front().value("SEAMNAME"));
        ui->list_W2->addItem(asere);
    }
}

void removeListSame(QStringList *list)
{
    for (int i = 0; i < list->count(); i++)
    {
        for (int k = i + 1; k <  list->count(); k++)
        {
            if ( list->at(i) ==  list->at(k))
            {
                list->removeAt(k);
                k--;
            }
        }
    }
}


DB_Keys MainWindow::getVaildKeys(DB_Types &db_tys)
{
    auto insertsTable = SystemVal::GetInstance()->dbTables; //! 提取出需要写的表格
    QSqlQuery query(SystemVal::GetInstance()->writes);      //! 新表的
    QString selectTabl_Data = "SELECT * FROM %1 WHERE ENABLED=1";
    QString keys = "PRAGMA table_info('%1')";

    DB_Keys ret;
    auto old_Data = SystemVal::GetInstance()->old_Data;     //! 获取老数据
    //! 每张有效表都遍历以下
    for(auto t:insertsTable){
        MULT_ROW ddd = old_Data.first()[t];
        if(ddd.isEmpty()){
            continue;
        }
        auto oldZiDuan =ddd.front().keys();
        auto ns = keys.arg(t);
        query.exec(ns);
        QStringList t_key;  //! 该表的所有字段
        QStringList n_key;  //! 含有的字段
        QMap<QString,QVariant> n_type;  //! 含有的字段
        while (query.next()){
            t_key.push_back(query.value(1).toString());
            n_type[query.value(1).toString()] = (query.value(2));
            oldZiDuan.push_back(query.value(1).toString());
        }

        removeListSame(&t_key);
        //! 提取出要填写的字段
        for(auto kk:oldZiDuan){
            if(t_key.contains(kk)){
                n_key.push_back(kk);
            }else{

            }
        }
        removeListSame(&n_key);

//        QLOG_LINE<< t << "拥有的字段" << n_key;
//        QLOG_LINE << "";
        ret[t] = n_key;
        db_tys[t] = n_type;
    }
    return ret;
}

void MainWindow::appendBuf(QString val)
{
    auto m_new = buf->stringList();
    if(m_new.contains(val)){

    }else{
        m_new.append(val);
        buf->setStringList(m_new);
    }
}

void MainWindow::showDetails(int id,QString seamname)
{
    QString shows = "焊缝名称:%1 \n";
    shows += "SEAMID:%2 \n";
    shows += "CADID:%3 \n";
    shows += "焊缝类型:%4 ";
    auto CADID = SystemVal::GetInstance()->old_Data[id]["SEAMINFO"].front()["CADID"];
    auto SEAMTYPE = SystemVal::GetInstance()->old_Data[id]["SEAMINFO"].front()["SEAMTYPE"];

    if(seamname.isEmpty()){
        seamname = SystemVal::GetInstance()->old_Data[id]["SEAMINFO"].front()["SEAMNAME"];
    }
    shows = shows.arg(seamname).arg(id).arg(CADID).arg(SEAMTYPE);
    QMessageBox::information(nullptr,"详细信息",shows);
}

void MainWindow::highLight(QStringList v)
{
    for(auto &s:v){
        auto liten = ui->list_W2->findItems(s,Qt::MatchExactly);
        for(auto &item:liten){
            item->setBackground(Qt::darkGray);
        }
    }
}

void MainWindow::appendLog(QString lo)
{
    out << lo;
}

void MainWindow::writeLogs(QString f)
{
    QFile file(f);
    file.open(QIODevice::WriteOnly | QIODevice::Truncate);
    QTextStream sds(&file);
    for(auto l:out){
        sds << l <<"\n";
    }
    file.close();
    out.clear();
}

void MainWindow::writeErrorLog(QString f)
{
    QFile file(f);
    file.open(QIODevice::WriteOnly | QIODevice::Truncate);  //! 覆盖式填充
    QTextStream sds(&file);
    for(auto l:errors){
        sds << l <<"\n";
    }
    file.close();
    errors.clear();
}

//! 验证cad数据
void MainWindow::insertCads(QStringList list,QSqlQuery query)
{
    QString _temp ="SELECT CADCODE FROM CAD WHERE CADID='%1'";
    query.exec(_temp);

    QStringList M_KEYS; //! CAD表拥有的字段名
    QString keys = "PRAGMA table_info('CAD')";
    query.exec(keys);
    while (query.next()) {
        if(query.value(1).toString().isEmpty()){
            continue;
        }else{
            auto s = query.value(1).toString();
            if("CADCODE" == s){

            }else{
                M_KEYS.push_back(s);
            }
        }
    }


    QString tar = "INSERT INTO CAD(";
    for(int i =0;i<M_KEYS.size()-1;i++){
        tar += M_KEYS[i];
        tar += ",";
    }
    tar += M_KEYS.back();
    tar +=") VALUES (";

    for(int i =0;i<M_KEYS.size()-1;i++){
        tar += "?";
        tar += ",";
    }
    tar += "?";
    tar +=")";

    auto &old_cad = SystemVal::GetInstance()->cad_Data;
    for(auto it = old_cad.begin();it!=old_cad.end();it++){
        auto cadid = (*it)["CAD"].first()["CADID"];
        if(list.contains(cadid) && (!inserted_cadid.contains(cadid))){
            query.prepare(tar);
            for(auto ke:M_KEYS){
               query.addBindValue((*it)["CAD"].first()[ke]);
            }
            query.exec();
            inserted_cadid.append(cadid);
        }else{
            //! 非选择的CAD不会被写入
        }
    }


}

//! 将选中的提交到
void MainWindow::on_tb_move2buf_clicked()
{
    auto sels = ui->list_W2->selectedItems();
    for(auto &item:sels){
        auto push1 = item->text();
        appendBuf(push1);
    }
    ui->list_W2->setCurrentRow(-1);
}

//! 写入数据库
void MainWindow::on_actionWrite_triggered()
{
    ui->progressBar->setValue(0);
    cur_ValidKeys.clear();
    auto slite = buf->stringList();
    highLight(slite);
    const auto old_Data = SystemVal::GetInstance()->old_Data;     //! 获取老数据
    const auto insertsTable = SystemVal::GetInstance()->dbTables;

    QSqlQuery query(SystemVal::GetInstance()->writes);      //! 新表的
    QString selectTabl_Data = "SELECT * FROM %1 WHERE ENABLED=1";
    QString keys = "PRAGMA table_info('%1')";

    QString insertRule = "INSERT INTO %1 (%2) VALUES (%3)";
    QString upds = "UPDATE SQLITE_SEQUENCE SET  SEQ=(SELECT max(SEAMID) from SEAMINFO) WHERE NAME='SEAMINFO';";
    query.exec(upds);
    cur_ValidKeys = getVaildKeys(db_tys);
    const auto ValidKeys = cur_ValidKeys;

    int litsize = slite.size();
    int inded_szz = 0;
    QSet<QString> cad_lists;    //! 准备插入cad数据表
    for(const auto s:slite){  //! 读取要插入的数据门
        int curInsert = s.toUInt(); //! 当前要插入的老seamid
        QLOG_LINE << "即将插入一条焊缝数据:" << s;
        query.exec("SELECT max(SEAMID) from SEAMINFO");
        int last = -1;
        int m_new = -1;
        while (query.next()) {
            last = query.value(0).toInt();
        }
        if(-1 == last){
            m_new = 1;
        }else{
            m_new = last + 1;
        }
        //**NEW : CADID
        // old_Data[curInsert]["SEAMINFO"]["CADID"];
        for(const auto t:insertsTable){
            QLOG_LINE <<curInsert << t << ":该表的数据个数:" << old_Data[curInsert][t].size();
            auto sdsdsdsd = old_Data[curInsert][t];
            //! 计算要填入的数据
            for (const auto vvvs:old_Data[curInsert][t]) {
                QString mquery = insertRule.arg(t);
                QStringList values;
                QStringList inKeys = ValidKeys[t]; //! 实际要插入的字段

                QString kkkkk ,vvvvvv;
                for(const auto k:ValidKeys[t]){   //! k:要填写的字段
                    const auto val = vvvs[k];
                    if(k == "SEAMID"){
                        if(t == "SEAMINFO"){
                            //! 不插入
                            inKeys.removeOne("SEAMID");
                        }else{
                            const QString val = QString::number(m_new);
                            values.push_back(val);
                            vvvvvv += (val + ",");
                        }
                    }else{
                        values.push_back(val);
                        if("TEXT" == db_tys[t][k].toString()){
                            vvvvvv += ("'" + val + "',");
                        }else{
                            vvvvvv += (val + ",");
                        }
                    }
                    if(t == "SEAMINFO" && k == "CADID"){
                        cad_lists.insert(val);
                    }
                }


                for(int i = 0;i<inKeys.size();i++){
                    kkkkk += (inKeys[i] + ",");
                }


                vvvvvv.chop(1);
                kkkkk.chop(1);


                mquery = mquery.arg(kkkkk).arg(vvvvvv);
                query.exec(mquery);

                appendLog(mquery);
                auto err = query.lastError().text();
                if(!err.isEmpty()){
                    QLOG_LINE <<  mquery << "\r\n";
                    errors.append(err);
                    errors.append(mquery);
                    // QLOG_LINE << t << ":" << err << mquery << "\n";
                }
            }
        }
        QStringList lissff = cad_lists.values();
        insertCads(lissff,query);

        inded_szz++;
        double pgr = (inded_szz*1.0/litsize) * 100.0;
        ui->progressBar->setValue(pgr);
    }
    writeLogs("Log.txt");
    db_tys.clear();
    QStringList ddd2121;
    buf->setStringList(ddd2121);
}

void MainWindow::on_tb_all_clicked()
{
    auto all = ui->list_W2->count();
    for(int i = 0;i<all;i++){
        auto s = ui->list_W2->item(i)->text();
        appendBuf(s);
    }
}



void MainWindow::on_list_W2_itemDoubleClicked(QListWidgetItem *item)
{
    auto id = item->text().toUInt();
    auto seamname = item->toolTip();
    showDetails(id,seamname);
}

void MainWindow::on_list_W1_doubleClicked(const QModelIndex &index)
{
    auto id = index.data().toUInt();
    auto seamname = index.data( Qt::ToolTipRole).toString();
    showDetails(id,seamname);
}

void MainWindow::on_tb_del_sel_clicked()
{
    auto sels = ui->list_W1->currentIndex();
    buf->removeRows(sels.row(),sels.column());
    auto stl = buf->stringList();
    stl.removeOne(sels.data().toString());
    buf->setStringList(stl);
    ui->list_W1->setCurrentIndex(sels);
}

void MainWindow::on_actionSame_triggered()
{
    Details *detail = new Details;
    detail->setHasKey(cur_ValidKeys);
    detail->show();
}
